import { _decorator, BufferAsset, Component, Node } from 'cc';
import Socket from '../../../Core/Net/Socket';
import UrlEnum from '../../../Core/Res/UrlEnum';
import Instance from '../../../Core/Utils/Instance';
import ProtoBufManager from '../../proto/ProtoBufManager';
import { ProtocolHandler } from './AbstractModel';
import TimerMgr from '../../../Core/Timer/TimerMgr';
import { GameModels } from './GameModels';
import { protoCmd } from '../../proto/protoCmd';
import { ViewManager } from '../base/ViewManager';
import ModuleWindow from '../window/ModuleWindow';
import WindowObject from '../window/WindowObject';
export class SocketManager {
    private ws: Socket = null;
    private _callbackDict: Object;
    public static get ins(): SocketManager {
        return Instance.get(SocketManager);
    }
    public init(): void {
        this._callbackDict = {};
        if (!this.ws) {
            this.ws = new Socket();
        }
        this.ws.onMessage = this.onMessage.bind(this);
        this.ws.onOpen = () => {
            console.log("Socket链接成功")
            TimerMgr.ins.add(10000, -1, this.send_heartPing, this);
            GameModels.login.send_login();
        };
        this.ws.onClose = this.socketClose.bind(this);
        this.ws.onError = this.socketError.bind(this);
    }
    /**
     * 连接 WebSocket 服务器
     * @returns 无返回值
     */
    public connect() {
        this.ws.connect(`${UrlEnum.socketip}`);
    }
    private onMessage(binary: Uint8Array) {
        // let param = ProtoBufManager.ins.pbCmd.ProtocolParam.decode(binary);
        // console.log(param)
        let param: protoCmd.ProtocolParam = null;
        try {
            param = ProtoBufManager.ins.pbCmd.ProtocolParam.decode(binary);
        } catch (error) {
            console.log(`解析数据错误：`, error);
        }
        if (!param) {
            return;
        }
        const protocolID = param.type;
        const response = param.response;
        if (protocolID == `globalHeartPing`) {
            // console.log(`收到心跳包：`, param);
            return;
        }
        console.log(`收到数据：`, param);
        if (response.errorMessage != `ok`) {
            ViewManager.ins.showtips(`${response.errorMessage}`);
            return;
        }
        const handlers: Array<ProtocolHandler> = this._callbackDict[protocolID];
        if (handlers) {
            for (let i = 0; i < handlers.length; ++i) {
                handlers[i].apply(response[protocolID]);
            }
        } else {
            console.log(`未注册协议回调：`, protocolID);
        }
    }
    // 发送
    public sendRequest(msgId: string, req: any) {
        const msg = ProtoBufManager.ins.pbCmd.ProtocolParam.create();
        msg.type = msgId;
        msg.request = ProtoBufManager.ins.pbCmd.Request.create();
        msg.request[msgId] = req;
        const u8a: Uint8Array = ProtoBufManager.ins.pbCmd.ProtocolParam.encode(msg).finish();
        console.log(`发送数据：`, msg);
        try {
            this.ws.send(u8a.slice().buffer);
        } catch (e) {
            console.log(e)
        }
    }
    private socketClose(): void {
        console.log("Socket链接已关闭");
        TimerMgr.ins.remove(this.send_heartPing, this);
        // ModuleWindow.ins.openWindow(WindowObject.ins.ReconnectWindow);
    }
    private socketError(): void {
        console.log("Socket链接发生错误");
        TimerMgr.ins.remove(this.send_heartPing, this);
        // ModuleWindow.ins.openWindow(WindowObject.ins.ReconnectWindow);
    }
    /**
     * 发送心跳包
     * @returns 无返回值
     */
    private send_heartPing(): void {
        const heart: protoCmd.ProtocolParam = ProtoBufManager.ins.pbCmd.ProtocolParam.create();
        heart.type = `globalHeartPing`;
        heart.request = ProtoBufManager.ins.pbCmd.Request.create();
        heart.request.globalHeartPing = ProtoBufManager.ins.pbCmd.globalHeartPing.create();
        heart.request.globalHeartPing.sign = Date.now();
        this.ws.send(ProtoBufManager.ins.pbCmd.ProtocolParam.encode(heart).finish().slice().buffer);
    }
    /**
     *  注册协议处理器
     *
     * @param protocolID 协议ID
     * @param handler 协议处理器
     * @returns 无返回值
     */
    public registerHandler(protocolID: any, handler: ProtocolHandler): void {
        // var callbacks: Object = this._callbackDict[protocolID];
        if (this._callbackDict[protocolID] == null) {
            this._callbackDict[protocolID] = [];
        }
        var handlers: Array<ProtocolHandler> = this._callbackDict[protocolID];
        for (var i: number = 0; i < handlers.length; ++i) {
            if (handlers[i] == handler) {
                return;
            }
        }
        handlers.push(handler);
    }
    /**
  * 注销协议回调
  */
    public unregisterHandler(protocolID: number, handler: ProtocolHandler): void {
        var handlers: Array<ProtocolHandler> = this._callbackDict[protocolID];
        for (var i: number = 0; i < handlers.length; ++i) {
            if (handlers[i] == handler) {
                handlers.splice(i, 1);
                return;
            }
        }
    }
}


